﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace WorkFlowCore.EventHandlers
{
    public class EventManager
    {
        private IServiceProvider serviceProvider;
        private static object objLock = new object();

        public EventManager(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }

        private static Dictionary<Type, List<Type>> eventSubscribes;
        static EventManager()
        {
            eventSubscribes = new Dictionary<Type, List<Type>>();
        }

        public static void Subscribe(Type handlerType, Type handler)
        {
            lock (objLock)
            {
                if (!eventSubscribes.ContainsKey(handlerType))
                    eventSubscribes.Add(handlerType, new List<Type> { });
            }

            eventSubscribes[handlerType].Add(handler);


        }

        public static void Subscribe(Type handlerType)
        {
            if (typeof(ISendTaskEventHandler).IsAssignableFrom(handlerType))
            {
                Subscribe(typeof(ISendTaskEventHandler), handlerType);
            }
            else if (typeof(ITaskFinishedEventHandler).IsAssignableFrom(handlerType))
                Subscribe(typeof(ITaskFinishedEventHandler), handlerType);
        }
        public static void Subscribe<EventHandler>() where EventHandler : IEventHandler
        {
            Subscribe(typeof(EventHandler));
        }

        /// <summary>
        /// 从 程序集注册
        /// </summary>
        /// <param name="assemblies"></param>
        public static void RegisterSubscriptions(params Assembly[] assemblies)
        {
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes().Where(t => typeof(IEventHandler).IsAssignableFrom(t));

                foreach (var type in types)
                {
                    Subscribe(type);
                }
            }
        }

        private void ResoleHandler<Handler>(Action<Handler> handlerFun) where Handler : IEventHandler
        {
            var handlerType = typeof(Handler);
            if (!eventSubscribes.ContainsKey(handlerType)) return;
            foreach (var handler in eventSubscribes[handlerType])
            {
                try
                {
                    handlerFun?.Invoke((Handler)serviceProvider.GetService(handler));
                }
                catch (Exception ex)
                {
                    //
                }
            }
        }

        public void TriggerSendTask(WorkTasks.WorkTask workTask, WorkTasks.WorkStep workStep)
        {
            ResoleHandler<ISendTaskEventHandler>(handler =>
            {
                handler.Trigger(workTask, workStep);
            });
        }
        public void TriggerTaskFinished(WorkTasks.WorkTask workTask)
        {
            ResoleHandler<ITaskFinishedEventHandler>(handler =>
            {
                handler.Trigger(workTask);
            });
        }
        public void TriggerTaskStateChange(WorkTasks.WorkTask workTask, WorkTasks.WorkTaskStatus workTaskStatus)
        {
            ResoleHandler<ITaskStateChangeEventHandler>(handler =>
            {
                handler.Trigger(workTask, workTaskStatus);
            });
        }
    }
}
